<?php
/**
 * Curl.php
 *
 * 飞信服务器通信类
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://momoger.com/license
 *
 * @category	App
 * @package 	App_Util
 * @subpackage 	Fetion
 * @author 		Guya
 * @version    	1.0
 * @copyright  	Copyright © 2009 www.momoger.com All Rights Reserved.
 * @license    	http://momoger.com/license     New BSD License
 */

/**
 * 飞信服务器通信类
 *
 * @category	App
 * @package 	App_Util
 * @subpackage 	Fetion
 * @copyright  	Copyright © 2009 www.momoger.com All Rights Reserved.
 * @license    	http://momoger.com/license     New BSD License
 */
class App_Util_Fetion_Curl {
	/**
	 * Curl 连接句柄
	 *
	 * @var resource
	 */
	protected $handle = null;

	/**
	 * Curl 配置选项
	 *
	 * @var array
	 */
	protected $options = array();

	/**
	 * Curl 请求结果
	 *
	 * @var string
	 */
	protected $reponse = null;

	/**
	 * Curl 执行系统信息
	 *
	 * @var array
	 */
	protected $reponseInfo = array();

	/**
	 * 错误信息
	 *
	 * @var array
	 */
	protected $error = array('errno' => 0, 'error' => 'ok');

	/**
	 * 构造函数
	 *
	 */
	public function __construct() {
		//
	}

	/**
	 * 请求飞信服务器信息配置
	 *
	 * @param string $post_data 发送POST数据
	 * @param string $fetion_url 飞信请求地址
	 * @param string $fetion_version 飞信客户端版本号
	 * @return App_Util_Fetion_Curl
	 */
	public function setRequestOption($post_data = '', $fetion_url = null, $fetion_version = null) {

		//clear the options
		$this->options = array();

		//the request url
		if ($fetion_url) {
			$this->setOption(CURLOPT_URL, $fetion_url);
		}

		//option lists
		$opts = array(
			CURLOPT_RETURNTRANSFER => true,		//使用结果返回模式代替直接输出模式
			CURLOPT_POST => true,				//使用POST模式提交请求
			CURLOPT_HEADER => false,			//不接收头信息
			CURLOPT_SSL_VERIFYPEER => false,	//不验证SSL
			CURLOPT_SSL_VERIFYHOST => 0,		//不验证SSL主机
			CURLOPT_FOLLOWLOCATION => true,		//允许重定向
			CURLOPT_MAXREDIRS => 10,			//最多允许10次从定向
			CURLOPT_POSTFIELDS => $post_data	//post发送数据内容
		);

		//set the fetion request options
		$this->setOption($opts);

		if ($fetion_version) {
			$this->setOption(CURLOPT_USERAGENT, 'User-Agent: IIC2.0/PC ' . $fetion_version);	//模拟Agent信息
		}

		return $this;
	}

	/**
	 * 发送 Curl 请求
	 *
	 * @return boolean
	 */
	public function request($keep_connect = false) {
		if (count($this->options)) {

			if(null === $this->handle) {
				//init the curl request handle
				$this->handle = curl_init();
			}

			//set the option at once
			//curl_setopt_array($this->handle, $this->options);

			//set the option one by noe
			$setOptResult = true;
			foreach ($this->options as $k => $v) {
				if (!curl_setopt($this->handle, $k, $v)) {
					$setOptResult = false;
					$this->error['errno'] = curl_errno($this->handle);
					$this->error['error'] = curl_error($this->handle);
					break;
				}
			}

			//check set all option is success
			if (!$setOptResult) {
				//close the curl session
				curl_close($this->handle);
				$this->handle = null;

				return false;
			}

			//execute request by curl
			$this->reponse = curl_exec($this->handle);

			//check the execute result
			if (false === $this->reponse) {
				$this->error['errno'] = curl_errno($this->handle);
				$this->error['error'] = curl_error($this->handle);

				//close the curl session
				curl_close($this->handle);
				$this->handle = null;

				return false;
			}

			//get the curl execute information
			$this->reponseInfo = curl_getinfo($this->handle);

			if (!$keep_connect) {
				//close the curl session
				curl_close($this->handle);
				$this->handle = null;
			}

			return true;

		} else {
			$this->error['errno'] = 0;
			$this->error['error'] = 'Not any option set!';
			return false;
		}
	}

	/**
	 * 获取CURL执行结果
	 *
	 * @return string
	 */
	public function getReponse() {
		return $this->reponse;
	}

	/**
	 * 获取CURL执行结果信息
	 *
	 * @return array
	 */
	public function getCurlInfo() {
		return $this->reponseInfo;
	}

	/**
	 * 获取所有的配置选项
	 *
	 * @return array
	 */
	public function getOptions() {
		return $this->options;
	}

	/**
	 * 获取错误信息
	 *
	 * @return string
	 */
	public function getErrorMsg() {
		return '[' . $this->error['errno'] . ']: ' . $this->error['error'];
	}

	/**
	 * 配置CURL选项
	 *
	 * @param mixed $key 配置选项数组/key
	 * @param mixed $value 配置选项值
	 * @return App_Util_Fetion_Curl
	 */
	protected function setOption($key, $value = null) {
		if (is_array($key)) {
			//$this->options = array_merge($this->options, $key);
			foreach ($key as $k => $v) {
				$this->options[$k] = $v;
			}
		} else {
			$this->options[$key] = $value;
		}
		return $this;
	}
}